﻿using FreeSql;
using Microsoft.Extensions.Configuration;
using Simple.Contracts.Contracts;
using Simple.Contracts.Models.Common;
using Simple.Repository;
using Simple.Repository.SimpleEntitys;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using TencentCloud.Sms.V20190711;
using TencentCloud.Sms.V20190711.Models;

namespace Simple.Services.Services
{
    /// <summary>
    /// 短信
    /// </summary>
    public class TencentCloudSmsService : BaseService, ISmsService
    {
        private readonly SmsClient _smsClient;
        private readonly IConfiguration _configuration;
        private readonly bool _isEnableSmsSend;
        public TencentCloudSmsService(IConfiguration configuration, FreeSqlCloud freeSqlCloud, CurrentAccount currentAccount, SmsClient smsClient) : base(freeSqlCloud, currentAccount)
        {
            _smsClient = smsClient;
            _configuration = configuration;
            _isEnableSmsSend = bool.Parse(configuration["TencentCloud:IsEnableSmsSend"]!.ToString());
        }

        /// <summary>
        /// 发送短信验证码
        /// </summary>
        /// <param name="phones"></param>
        /// <param name="templateID"></param>
        /// <param name="templateParams"></param>
        /// <returns></returns>
        private async Task Send(string[] phones, string templateID, string smsContent, string smsTag, string[] templateParams)
        {
            /* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
                * 您可以直接查询SDK源码确定SendSmsRequest有哪些属性可以设置
                * 属性可能是基本类型，也可能引用了另一个数据结构
                * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
            SendSmsRequest req = new SendSmsRequest();

            /* 基本类型的设置:
             * SDK采用的是指针风格指定参数，即使对于基本类型您也需要用指针来对参数赋值。
             * SDK提供对基本类型的指针引用封装函数
             * 帮助链接：
             * 短信控制台: https://console.cloud.tencent.com/smsv2
             * 腾讯云短信小助手: https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81 */
            /* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
            // 应用 ID 可前往 [短信控制台](https://console.cloud.tencent.com/smsv2/app-manage) 查看
            req.SmsSdkAppid = "1400523914";

            /* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名 */
            // 签名信息可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-sign) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-sign) 的签名管理查看
            req.Sign = "上海恩睦信息科技";

            /* 模板 ID: 必须填写已审核通过的模板 ID */
            // 模板 ID 可前往 [国内短信](https://console.cloud.tencent.com/smsv2/csms-template) 或 [国际/港澳台短信](https://console.cloud.tencent.com/smsv2/isms-template) 的正文模板管理查看
            // req.TemplateID = "449739";
            req.TemplateID = templateID;

            /* 模板参数: 模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致，若无模板参数，则设置为空 */
            //req.TemplateParamSet = new String[] { "1234" };
            req.TemplateParamSet = templateParams;

            /* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号*/
            //req.PhoneNumberSet = new String[] { "+8613711112222" };
            req.PhoneNumberSet = phones;

            /* 用户的 session 内容（无需要可忽略）: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
            req.SessionContext = "";

            /* 短信码号扩展号（无需要可忽略）: 默认未开通，如需开通请联系 [腾讯云短信小助手] */
            req.ExtendCode = "";

            /* 国内短信无需填写该项；国际/港澳台短信已申请独立 SenderId 需要填写该字段，默认使用公共 SenderId，无需填写该字段。注：月度使用量达到指定量级可申请独立 SenderId 使用，详情请联系 [腾讯云短信小助手](https://cloud.tencent.com/document/product/382/3773#.E6.8A.80.E6.9C.AF.E4.BA.A4.E6.B5.81)。 */
            req.SenderId = "";

            if (_isEnableSmsSend)
            {
                SendSmsResponse resp = await _smsClient.SendSms(req);
                foreach (var item in resp.SendStatusSet)
                {
                    var entity = new CompanySmsLogs()
                    {
                        CompanyId = _currentAccount.CompanyId,
                        RecipientPhone = item.PhoneNumber,
                        SenderEmployeeId = _currentAccount.EmployeeId,
                        SenderTime = DateTime.Now,
                        SmsContent = smsContent,
                        SmsTag = smsTag,
                        TencentCloudSmsRecordId = item.SerialNo,
                        TencentCloudSmsTemplateId = templateID
                    };
                    await _simpleFreeSql.Insert<CompanySmsLogs>(entity).ExecuteAffrowsAsync();
                }
            }
            else
            {
                foreach (var phone in phones)
                {
                    var entity = new CompanySmsLogs()
                    {
                        CompanyId = _currentAccount.CompanyId,
                        RecipientPhone = phone,
                        SenderEmployeeId = _currentAccount.EmployeeId,
                        SenderTime = DateTime.Now,
                        SmsContent = smsContent,
                        SmsTag = smsTag,
                        TencentCloudSmsRecordId = string.Empty,
                        TencentCloudSmsTemplateId = templateID
                    };
                    await _simpleFreeSql.Insert<CompanySmsLogs>(entity).ExecuteAffrowsAsync();
                }
            }
        }

        /// <summary>
        /// 注册密码
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task SendRegisterPassword(string phone, string password)
        {
            var templateID = "2534837";
            var smsContent = "初始密码为：{***}，若非本人操作，请勿泄露。";
            var smsTag = "注册密码";
            var phones = new string[1] { "+86" + phone };
            var templateParams = new string[1] { password };
            await Send(phones, templateID, smsContent, smsTag, templateParams);
        }

        /// <summary>
        /// 发送重置密码
        /// </summary>
        /// <param name="phone"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task SendResetPassword(string phone, string password)
        {
            var templateID = "2534838";
            var smsContent = "新密码为：{***}，若非本人操作，请勿泄露。";
            var smsTag = "重置密码";
            var phones = new string[1] { "+86" + phone };
            var templateParams = new string[1] { password };
            await Send(phones, templateID, smsContent, smsTag, templateParams);
        }

        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="phone"></param>
        /// <returns></returns>
        public async Task SendLoginCode(string phone, string code)
        {
            var templateID = "2548240";
            var smsContent = "验证码为：{***}，您正在登录，若非本人操作，请勿泄露。";
            var smsTag = "登录验证";
            var phones = new string[1] { "+86" + phone };
            var templateParams = new string[1] { code };
            await Send(phones, templateID, smsContent, smsTag, templateParams);
        }
    }
}
